/*
 * @Author: lokei
 * @Date: 2022-11-11 20:55:39
 * @LastEditors: lokei
 * @LastEditTime: 2023-06-08 13:30:41
 * @Description: 
 */
package cn.lokei.task.handler.message;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@Configuration
@PropertySource(value = { "file:conf/db.properties" })
public class SendMessageHandler {

	@Value("${debug.on:0}")
	private String debug_on;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void handler(MapRecord<String, String, String> record) {
        if(debug_on.equals("1")) {
            log.info("发送公众号模板消息：" + record.toString() );
        }
        String pid = record.getValue().get("pid");
        String type = record.getValue().get("type");
        if (type.equals("mp")) {
            Object mp_info = redisTemplate.opsForValue().get("proj:" + pid + ":mp");
            if (mp_info != null) {
                JSONObject mp_info_json = JSONObject.parseObject(mp_info.toString());
                String access_token_key = "mp_access_token" + "_" + mp_info_json.getString("appid");
                RestTemplate template = new RestTemplate();
                String access_token = (String) redisTemplate.opsForValue().get(access_token_key);
                if (access_token == null) {
                    try {
                        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}";
                        Map<String, Object> requestMap = new HashMap<>();
                        // JSONObject requestMap = new JSONObject();
                        requestMap.put("grant_type", "client_credential");
                        requestMap.put("appid", mp_info_json.getString("appid"));
                        requestMap.put("secret", mp_info_json.getString("secret"));

                        ResponseEntity<JSONObject> responseEntity = template
                                .getForEntity(url, JSONObject.class, requestMap);
                        HttpStatus statusCode = responseEntity.getStatusCode(); // 获取响应码
                        if(debug_on.equals("1")) {
                            log.info("获取公众号access_token状态：" + statusCode.toString() );
                        }
                        if (statusCode == HttpStatus.OK) {
                            JSONObject body = responseEntity.getBody();
                            if(debug_on.equals("1")) {
                                if(body != null) {
                                    log.info("获取公众号access_token Body：" + body.toString());
                                } else {
                                    log.info("获取公众号access_token Body：获取NULL");
                                }
                                
                            }
                            if (body != null && body.get("access_token") != null) {
                                access_token = body.getString("access_token");
                                Integer expires_in = body.getInteger("expires_in") - 5 * 60;
                                redisTemplate.opsForValue().set(access_token_key, access_token,
                                        expires_in,
                                        TimeUnit.SECONDS);
                            }
                        } else {
                            log.error("saas 服务访问失败！");
                            // throw new RuntimeException("saas 服务访问失败！");
                        }
                    } catch (Exception e) {
                        log.error(e.toString());
                        // throw new RuntimeException(e.toString());
                    }
                }
                if (access_token != null) {
                    // Template template = templateDao.queryAll()
                    String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="
                            + access_token;
                    Map<String, Object> requestMap = new HashMap<>();
                    requestMap.put("touser", record.getValue().get("touser"));
                    requestMap.put("template_id", record.getValue().get("template_id"));
                    if(record.getValue().get("url") != null && !record.getValue().get("url").equals("")) {
                        requestMap.put("url", record.getValue().get("url"));
                    }
                    Map<String, Object> data = new HashMap<>();
                    Integer keyword_amount = Integer.valueOf(record.getValue().get("keyword_amount"));
                    Map<String, Object> first = new HashMap<>();
                    first.put("value", record.getValue().get("first"));
                    first.put("color", "#173177");
                    data.put("first", first);
                    for (int i = 1; i <= keyword_amount; i++) {
                        Map<String, Object> keyword = new HashMap<>();
                        String keyword_str = record.getValue().get("keyword" + i);
                        JSONObject keyword_json = JSON.parseObject(keyword_str);
                        keyword.put("value", keyword_json.getString("value"));
                        keyword.put("color", "#173177");
                        data.put(keyword_json.getString("name"), keyword);
                    }
                    Map<String, Object> remark = new HashMap<>();
                    remark.put("value", record.getValue().get("remark"));
                    remark.put("color", "#173177");
                    data.put("remark", remark);
                    requestMap.put("data", data);
                    template.postForEntity(url, requestMap, JSONObject.class);
                }
            }
        } else if (type.equals("miniapp")) {
            Object miniapp_info = redisTemplate.opsForValue().get("proj:" + pid + ":miniapp");
            if (miniapp_info != null) {
                JSONObject miniapp_info_json = JSONObject.parseObject(miniapp_info.toString());
                String access_token_key = "miniapp_access_token" + "_" + miniapp_info_json.getString("appid");
                RestTemplate template = new RestTemplate();
                String access_token = (String) redisTemplate.opsForValue().get(access_token_key);
                if (access_token == null) {
                    try {
                        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}";
                        Map<String, Object> requestMap = new HashMap<>();
                        // JSONObject requestMap = new JSONObject();
                        requestMap.put("grant_type", "client_credential");
                        requestMap.put("appid", miniapp_info_json.getString("appid"));
                        requestMap.put("secret", miniapp_info_json.getString("secret"));

                        ResponseEntity<JSONObject> responseEntity = template
                                .getForEntity(url, JSONObject.class, requestMap);
                        HttpStatus statusCode = responseEntity.getStatusCode(); // 获取响应码
                        if (statusCode == HttpStatus.OK) {
                            JSONObject body = responseEntity.getBody();
                            if (body != null && body.get("access_token") != null) {
                                access_token = body.getString("access_token");
                                Integer expires_in = body.getInteger("expires_in") - 5 * 60;
                                redisTemplate.opsForValue().set(access_token_key, access_token,
                                        expires_in,
                                        TimeUnit.SECONDS);
                            }
                        } else {
                            log.error("saas 服务访问失败！");
                            // throw new RuntimeException("saas 服务访问失败！");
                        }
                    } catch (Exception e) {
                        log.error(e.toString());
                        // throw new RuntimeException(e.toString());
                    }
                }
                if (access_token != null) {
                    // Template template = templateDao.queryAll()
                    String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="
                            + access_token;
                    Map<String, Object> requestMap = new HashMap<>();
                    requestMap.put("touser", record.getValue().get("touser"));
                    requestMap.put("template_id", record.getValue().get("template_id"));
                    Map<String, Object> data = new HashMap<>();
                    JSONArray data_array = JSON.parseArray(record.getValue().get("data"));
                    for (Object entry : data_array) {
                        JSONObject item = (JSONObject) entry;
                        Map<String, Object> value = new HashMap<>();
                        value.put("value", item.getString("value"));
                        data.put(item.getString("name"), value);
                    }
                    requestMap.put("data", data);
                    requestMap.put("miniprogram_state", "formal");
                    requestMap.put("lang", "zh_CN");
                    ResponseEntity<JSONObject> responseEntity = template.postForEntity(url, requestMap,
                            JSONObject.class);
                    HttpStatus statusCode = responseEntity.getStatusCode(); // 获取响应码
                    if (statusCode == HttpStatus.OK) {
                        JSONObject body = responseEntity.getBody();
                        if (body != null) {
                            Integer errorCode = body.getInteger("errcode");
                            if (errorCode != 0) {
                                log.info(body.toJSONString());
                            }
                        }
                    }
                }
            }
        }
    }
}
